package com.dy.yunying.biz.service.datacenter.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dy.yunying.api.constant.Constant;
import com.dy.yunying.api.datacenter.vo.AdDataAnalysisVO;
import com.dy.yunying.api.datacenter.vo.PlanAttrAnalyseSearchVo;
import com.dy.yunying.api.datacenter.vo.PlanBaseAttrVo;
import com.dy.yunying.biz.dao.datacenter.impl.AdPlanAttrStatDao;
import com.dy.yunying.biz.service.datacenter.PlanAnalysisService;
import com.dy.yunying.biz.service.manage.AdRoleGameService;
import com.dy.yunying.biz.service.manage.AdRoleUserService;
import com.dy.yunying.biz.service.manage.GameChannelPackService;
import com.dy.yunying.biz.utils.AdPlanUtil;
import com.dy.yunying.biz.utils.DateUtils;
import com.pig4cloud.pig.admin.api.entity.SysDictItem;
import com.pig4cloud.pig.admin.api.feign.RemoteDictService;
import com.pig4cloud.pig.api.entity.AdPlan;
import com.pig4cloud.pig.api.enums.GdtScheduleTypeEnum;
import com.pig4cloud.pig.api.feign.RemoteAccountService;
import com.pig4cloud.pig.api.feign.RemoteAdPlanService;
import com.pig4cloud.pig.api.util.Constants;
import com.pig4cloud.pig.api.vo.PlanGdtAttrAnalyseReportVo;
import com.pig4cloud.pig.api.vo.PlanTtAttrAnalyseReportVo;
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
import com.pig4cloud.pig.common.core.constant.enums.PlanAttrStatTypeEnum;
import com.pig4cloud.pig.common.core.constant.enums.PlatformTypeEnum;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.service.PigUser;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 计划属性分析表相关方法
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PlanAnalysisServiceImpl implements PlanAnalysisService {

	private static final String NATURAL_FLOW = "自然量";

	private static final Map<String, String> CONVERT_DATA_TYPE_MAP = new HashMap<String, String>() {{
		put("ONLY_ONE", "仅一次");
		put("EVERY_ONE", "每一次");
	}};

	private final AdPlanAttrStatDao adPlanAttrStatDao;

	private final AdRoleUserService adRoleUserService;

	private final AdRoleGameService adRoleGameService;

	private final RemoteAccountService remoteAccountService;

	private final RemoteAdPlanService remoteAdPlanService;

	private final GameChannelPackService gameChannelPackService;

	private final RemoteDictService remoteDictService;

	@Override
	public R<Long> count(PlanAttrAnalyseSearchVo req) {
		try {
			// 当前用户
			final PigUser user = SecurityUtils.getUser();
			List<Integer> ownerRoleUserIds = adRoleUserService.getOwnerRoleUserIds();
			// 当前账号及管理的账号
			List<Integer> roleUserIdList = new ArrayList<>();
			req.setRoleUserIdList(roleUserIdList);
			roleUserIdList.add(user.getId());
			if (CollectionUtils.isNotEmpty(ownerRoleUserIds)) {
				roleUserIdList.addAll(ownerRoleUserIds);
			}
			// 授权的广告账户
			List<String> roleAdAccountList = new ArrayList<>();
			req.setRoleAdAccountList(roleAdAccountList);
			final List<String> accountList2 = remoteAccountService.getAccountList2(roleUserIdList, SecurityConstants.FROM_IN);
			if (CollectionUtil.isNotEmpty(accountList2)) {
				roleAdAccountList.addAll(accountList2);
			}
			// 判断是否管理员
			if (SecurityUtils.getRoles().contains(1)) {
				req.setIsSys(1);
			}
			List<String> qcs = req.getQueryColumn();
			if (CollectionUtil.isEmpty(qcs)) {
				req.setQueryColumn(PlanAttrStatTypeEnum.ADID.V());
			} else if (!PlanAttrStatTypeEnum.contain(qcs.get(0))) {
				req.setQueryColumn(PlanAttrStatTypeEnum.ADID.V());
			} else {
				req.setQueryColumn(qcs.get(0));
			}
			req.setGameIds(adRoleGameService.getOwnerRoleGameIds());
			//查询总记录数
			Long count = adPlanAttrStatDao.countDataTotal(req);
			return R.ok(count);
		} catch (Exception e) {
			log.error("countDataTotal:[{}]", e);
			return R.failed("计划属性总记录数查询失败");
		}
	}

	@Override
	public R page(Page page, PlanAttrAnalyseSearchVo searchVo) {
		// 当前用户
		final PigUser user = SecurityUtils.getUser();
		List<Integer> ownerRoleUserIds = adRoleUserService.getOwnerRoleUserIds();
		// 当前账号及管理的账号
		List<Integer> roleUserIdList = new ArrayList<>();
		searchVo.setRoleUserIdList(roleUserIdList);
		roleUserIdList.add(user.getId());
		if (CollectionUtils.isNotEmpty(ownerRoleUserIds)) {
			roleUserIdList.addAll(ownerRoleUserIds);
		}
		// 授权的广告账户
		List<String> roleAdAccountList = new ArrayList<>();
		searchVo.setRoleAdAccountList(roleAdAccountList);
		final List<String> accountList2 = remoteAccountService.getAccountList2(roleUserIdList, SecurityConstants.FROM_IN);
		if (CollectionUtil.isNotEmpty(accountList2)) {
			roleAdAccountList.addAll(accountList2);
		}
		// 判断是否管理员
		if (SecurityUtils.getRoles().contains(1)) {
			searchVo.setIsSys(1);
		}
		List<String> qcs = searchVo.getQueryColumn();
		if (CollectionUtil.isEmpty(qcs)) {
			searchVo.setQueryColumn(PlanAttrStatTypeEnum.ADID.V());
		} else if (!PlanAttrStatTypeEnum.contain(qcs.get(0))) {
			searchVo.setQueryColumn(PlanAttrStatTypeEnum.ADID.V());
		} else {
			searchVo.setQueryColumn(qcs.get(0));
		}
		searchVo.setGameIds(adRoleGameService.getOwnerRoleGameIds());
		//根据投放人获取广告账户
		List<PlanBaseAttrVo> values = adPlanAttrStatDao.selectPlanAttrAnalyseReoport(searchVo);
		dealPlan(values, searchVo);
		dealZrl(values, searchVo);
		return dealStatType(values, searchVo);
	}

	private void dealZrl(List<PlanBaseAttrVo> values, PlanAttrAnalyseSearchVo searchVo) {
		if (CollectionUtil.isEmpty(values) || (!Objects.isNull(searchVo.getCycleType()) && searchVo.getCycleType() == 4)) {
			return;
		}
		if (searchVo.getQueryColumn().contains(PlanAttrStatTypeEnum.ADID.V()) || searchVo.getQueryColumn().contains(PlanAttrStatTypeEnum.ADVERTISERID.V())) {
			values.forEach(v -> {
				if (StringUtils.isBlank(v.getId())) {
					v.setName(NATURAL_FLOW);
				}
			});
		}
	}


	private R dealStatType(List<PlanBaseAttrVo> values, PlanAttrAnalyseSearchVo searchVo) {

		switch (PlanAttrStatTypeEnum.get(CollectionUtil.isNotEmpty(searchVo.getQueryColumn()) ? searchVo.getQueryColumn().get(0) : Constant.EMPTTYSTR)) {
			case ADID:
				// 获取广告信息 TODO
				return doDealAdidStatType(values, searchVo.getCtype());
			default:
				return R.ok(values);
		}
	}

	private void dealPlan(List<PlanBaseAttrVo> values, PlanAttrAnalyseSearchVo searchVo) {
		if (CollectionUtils.isNotEmpty(values)) {
			if (searchVo.getQueryColumn().contains("appchl")) {
				//分包编码名称
				List<String> appChlArr = new ArrayList<>();
				if (ObjectUtils.isNotEmpty(values)) {
					values.forEach(dataAccount -> {
						String appchl = dataAccount.getId();
						if (StringUtils.isNotBlank(appchl)) {
							appChlArr.add(appchl);
						}
					});
				}
				List<String> distinctValue = appChlArr.stream().distinct().collect(Collectors.toList());
				List<Map<String, String>> appChlArrList = gameChannelPackService.queryAppChlName(distinctValue);
				Map<String, String> mapappChl = new HashMap<>();
				if (ObjectUtils.isNotEmpty(appChlArrList)) {
					appChlArrList.forEach(appChlData -> mapappChl.put(String.valueOf(appChlData.get("code")), appChlData.get("codeName")));
				}
				//封装数据
				values.forEach(data -> {
					// 分包编码名称
					String appchl = data.getId();
					data.setName(mapappChl.get(appchl) == null ? appchl : mapappChl.get(appchl));
				});
			}
		}
	}


	private R doDealAdidStatType(List<PlanBaseAttrVo> values, Integer ctype) {
		if (CollectionUtil.isEmpty(values)) {
			return R.ok(values);
		}
		if (!Objects.isNull(ctype) && ctype == Integer.parseInt(PlatformTypeEnum.TT.getValue())) {
			String adids = values.stream().map(PlanBaseAttrVo::getId).filter(StringUtils::isNotBlank).collect(Collectors.joining(Constant.COMMA));
			R<List<AdPlan>> adPlanDetail = null;
			if (StringUtils.isNotBlank(adids)) {
				adPlanDetail = remoteAdPlanService.getByAdids(adids);
				if (adPlanDetail.getCode() != 0) {
					return R.failed("获取广告详情失败");
				}
			}
			List<AdPlan> adPlans = Objects.isNull(adPlanDetail) ? null : adPlanDetail.getData();
			Map<String, AdPlan> adPlanMap = new HashMap<>();
			if (CollectionUtil.isNotEmpty(adPlans)) {
				adPlans.forEach(v -> adPlanMap.put(String.valueOf(v.getAdId()), v));
			}

			// 获取转化目标字典项
//			final Map<String, String> convertMapping = Optional.ofNullable(remoteDictService.getDictByType4Inner(SecurityConstants.FROM_IN, "tt_target_convert_type").getData()).orElse(Collections.emptyList()).stream().collect(Collectors.toMap(SysDictItem::getValue, SysDictItem::getLabel, (k1, k2) -> k1));
			return R.ok(values.stream().map(v -> {
				// 填充转化目标名称
//				final String convertDescri = this.getConvertDescri(v, convertMapping);
				v.setConvertDescri(this.getConvertDescri(v, ctype));

				PlanTtAttrAnalyseReportVo vo = BeanUtil.copyProperties(v, PlanTtAttrAnalyseReportVo.class);
				AdPlan adPlan = adPlanMap.get(vo.getId());
				vo.setAdStatus(Objects.isNull(adPlan) ? vo.getAdStatus() : adPlan.getStatus());
				vo.setGender(Objects.isNull(adPlan) ? Constants.EMPTTYSTR : adPlan.getGender());
				vo.setAge(Objects.isNull(adPlan) ? Constants.EMPTTYSTR : adPlan.getAge());
				vo.setRetargetingTagsExclude(Objects.isNull(adPlan) ? Constants.EMPTTYSTR : adPlan.getRetargetingTagsExclude());
				vo.setRetargetingTagsInclude(Objects.isNull(adPlan) ? Constants.EMPTTYSTR : adPlan.getRetargetingTagsInclude());
				vo.setRoiGoal(Objects.isNull(adPlan) ? vo.getRoiGoal() : adPlan.getRoiGoal());
				vo.setActionScene(Objects.isNull(adPlan) ? Constants.EMPTTYSTR : adPlan.getActionScene());
				vo.setActionWords(Objects.isNull(adPlan) ? Constants.EMPTTYSTR : adPlan.getActionWords());
				vo.setInterestCategories(Objects.isNull(adPlan) ? Constants.EMPTTYSTR : adPlan.getInterestCategories());
				vo.setInterestWords(Objects.isNull(adPlan) ? Constants.EMPTTYSTR : adPlan.getInterestWords());
				//是否为智能放量
				vo.setSmartVolume(Objects.isNull(adPlan) ? Constants.NO : Objects.isNull(adPlan.getAutoExtendEnabled()) || adPlan.getAutoExtendEnabled() != 1 ? Constants.NO : Constants.YES);
				vo.setBid(Objects.isNull(adPlan) ? vo.getBid() : adPlan.getBudget());
				vo.setBidType(Objects.isNull(adPlan) ? Constants.EMPTTYSTR : adPlan.getBudgetMode());
				vo.setCpaBid(Objects.isNull(adPlan) ? vo.getCpaBid() : adPlan.getCpaBid());
				vo.setConverType(Objects.isNull(adPlan) ? Constants.EMPTTYSTR : adPlan.getPricing());
				vo.setThrowCountLevel(Objects.isNull(adPlan) ? vo.getThrowCountLevel() : adPlan.getEstimateNum());
				vo.setInventoryType(Objects.isNull(adPlan) ? Constants.EMPTTYSTR : adPlan.getInventoryType());
				if (!Objects.isNull(adPlan) && GdtScheduleTypeEnum.SCHEDULE_FROM_NOW.getType().equals(adPlan.getScheduleType())) {
					vo.setThrowDays(Objects.isNull(adPlan) ? vo.getThrowDays() : (converDay(adPlan.getAdCreateTime(), DateUtil.format(new Date(), DateUtils.YYYY_MM_DD_HH_MM_SS), DateUtils.YYYY_MM_DD_HH_MM_SS)));
				} else {
					vo.setThrowDays(Objects.isNull(adPlan) ? vo.getThrowDays() : (converDay(adPlan.getStartTime(), adPlan.getEndTime(), DateUtils.YYYY_MM_DD_HH_MM)));
				}
				vo.setMaterialVos(Objects.isNull(adPlan) ? vo.getMaterialVos() : adPlan.getMaterialVos());
				return vo;
			}).collect(Collectors.toList()));
		} else if (!Objects.isNull(ctype) && ctype == Integer.parseInt(PlatformTypeEnum.GDT.getValue())) {
			String adids = values.stream().map(PlanBaseAttrVo::getId).filter(StringUtils::isNotBlank).collect(Collectors.joining(Constant.COMMA));
			R<List<PlanGdtAttrAnalyseReportVo>> adPlanDetail = null;
			if (StringUtils.isNotBlank(adids)) {
				adPlanDetail = remoteAdPlanService.getGdtByAdids(adids);
				if (adPlanDetail.getCode() != 0) {
					return R.failed("获取广告详情失败");
				}
			}
			List<PlanGdtAttrAnalyseReportVo> ad = Objects.isNull(adPlanDetail) ? null : adPlanDetail.getData();
			Map<String, PlanGdtAttrAnalyseReportVo> adPlanMap = new HashMap<>();
			if (CollectionUtil.isNotEmpty(ad)) {
				ad.forEach(v -> adPlanMap.put(String.valueOf(v.getId()), v));
			}

			// 获取转化目标字典项
//			final Map<String, String> convertMapping = Optional.ofNullable(remoteDictService.getDictByType4Inner(SecurityConstants.FROM_IN, "gdt_target_convert_type").getData()).orElse(Collections.emptyList()).stream().collect(Collectors.toMap(SysDictItem::getValue, SysDictItem::getLabel, (k1, k2) -> k1));
			return R.ok(values.stream().map(v -> {
				// 填充转化目标名称
//				final String convertDescri = this.getConvertDescri(v, convertMapping);
				v.setConvertDescri(this.getConvertDescri(v, ctype));

				PlanGdtAttrAnalyseReportVo vo = adPlanMap.get(v.getId());
				if (Objects.isNull(vo)) {
					vo = BeanUtil.copyProperties(v, PlanGdtAttrAnalyseReportVo.class);
				} else {
					BeanUtil.copyProperties(v, vo);
				}
				return vo;
			}).collect(Collectors.toList()));
		}
		return R.ok(values);
	}

	private Long converDay(String startTime, String endTime, String dateFormat) {
		try {
			long hour = DateUtil.between(DateUtil.parse(startTime, dateFormat), DateUtil.parse(endTime, dateFormat), DateUnit.HOUR, false);
			long day = hour % 24 > 0 ? 1 : 0;
			if (hour <= 24) {
				return day;
			} else {
				return DateUtil.between(DateUtil.parse(startTime, dateFormat), DateUtil.parse(endTime, dateFormat), DateUnit.DAY, false) + day;
			}
		} catch (Exception e) {
			return 0l;
		}
	}

	private String getConvertDescri(PlanBaseAttrVo data, int ctype) {
		final String convertName = data.getConvertName();
		String convertTargetEnumValue = AdPlanUtil.getConvertTargetEnumValue(convertName, ctype, null);
		String deepConvertEnumValue = AdPlanUtil.getDeepConvertEnumValue(data.getDeepConvert(), ctype, null);

		if (StringUtils.isNotBlank(deepConvertEnumValue)) {
			return convertTargetEnumValue + '-' + deepConvertEnumValue;
		} else if ("AD_CONVERT_TYPE_ACTIVE".equals(convertName) || "AD_CONVERT_TYPE_PAY".equals(convertName)) {
			return convertTargetEnumValue + "-无";
		} else {
			return convertTargetEnumValue;
		}
	}

	private String getConvertDescri(PlanBaseAttrVo data, Map<String, String> mapping) {
		final String convertDescri = mapping.get(data.getConvertName());
		final String deepConvertDescri = mapping.get(data.getDeepConvert());
		final String convertDataTypeDescri = CONVERT_DATA_TYPE_MAP.get(data.getConvertDataType());

		final StringBuilder convert = new StringBuilder();
		if (StringUtils.isNotBlank(convertDescri)) {
			convert.append(convertDescri);
		}
		if (StringUtils.isNotBlank(deepConvertDescri)) {
			convert.append("-").append(deepConvertDescri);
		} else if ("AD_CONVERT_TYPE_ACTIVE".equals(data.getConvertName()) || "AD_CONVERT_TYPE_PAY".equals(data.getConvertName())) {
			convert.append("-无");
		}
		if (StringUtils.isNotBlank(convertDataTypeDescri)) {
			convert.append("-").append(convertDataTypeDescri);
		}

		return convert.toString();
	}

}
